<?php
namespace app\admin\model;
use app\common\model\AdminBase;
class Config extends AdminBase{
    protected $tableName = 'config';
    protected $fields = [
        0   =>  'config_id', 
        1   =>  'type', 
        2   =>  'key', 
        3   =>  'value', 
        4   =>  'value_type',
        5   =>  'status',
        6   =>  'description',
        7   =>  'update_time'
    ];
    protected $zip_conf_list = [
        'filter_version' => 'filter_word',//定义需要打包的配置，如果定义了，则每次在其版本号变更都会更新zip数据包
    ];
    /**
     * @name 添加配置
     * @param array $data 添加的数据
     * @param int $value_type 值保存方式  0:string,1:serialize,2:json
     */
    public function addConfig($data = [],$value_type = 0){
        $data = $this->validateData($data);
        switch($value_type){
            //序列化
            case 1:
                $data['value'] = serialize((array)$data['value']);
                $data['value_type'] = 1;
                break;
            //json
            case 2:
                $data['value'] = json_encode((array)$data['value']);
                $data['value_type'] = 2;
                break;
            //字符串,不经过任何处理,默认
            case 0:
            default:
                $data['value_type'] = 0;
                break;
        }
        $data['update_time'] = NOW_TIME;
        return $this->add($data);
    }
    /**
     * @name 检测key是否已经存在
     */
    public function hasKey($key = '',$type = ''){
        $map = [];
        $type && $map['type'] = $type;
        $key && $map['key'] = $key;
        if(empty($map)){
            return false;
        }
        return $this->where($map)->count() > 0 ? true : false;
    }
    /**
     * @name 检测value是否已经存在
     */
    public function hasValue($value = '',$type = ''){
        $map = [];
        $type && $map['type'] = $type;
        $value && $map['value'] = $value;
        if(empty($map)){
            return false;
        }
        return $this->where($map)->count() > 0 ? true : false;
    }
    /**
     * @name 获取配置
     */
    public function getConfigList($type = '',$key = '',$limit = 10){
        $map = [];
        $type && $map['type'] = $type;
        $key && $map['key'] = $key;
        $list = $this->where($map)->order('update_time desc')->findPage($limit);
        if(!empty($list['data'])){
            foreach($list['data'] as &$v){
                $v['value'] = $this->getReValue($v['value'],$v['value_type']);
            }
        }
        return $list;
    }
    /**
     * @name 根据配置ID获取配置信息
     */
    public function getConfigById($config_id = 0){
        $conf = [];
        if($config_id){
            $conf = $this->where(['config_id'=>$config_id])->find();
            $conf['value'] = $this->getReValue($conf['value'],$conf['value_type']);
        }
        return $conf;
    }
    /**
     * @name 根据对应的条件,获取value值
     */
    public function getConfigValue($map = [],$key = ''){
        $value = [];
        if(is_array($map)){
           $value = $this->where($map)->field(['value','value_type'])->find();
           $value = $this->getReValue($value['value'],$value['value_type']);
        }
        return ($key && array_key_exists($key,$value)) ? $value[$key] : $value;
    }
    /**
     * @name 根据配置ID获取配置的key
     */
    public function getConfigKey($config_id = 0){
        if($config_id){
            return $this->getFieldByConfigId($config_id,'key');
        }
        return '';
    }
    /**
     * @name 根据配置ID获取配置的描述
     */
    public function getConfigDescription($config_id = 0){
        if($config_id){
            return $this->getFieldByConfigId($config_id,'description') ?: '';
        }
        return '';
    }
    /**
     * @name 反解析value值
     */
    protected function getReValue($value = '',$value_type = 0){
        switch($value_type){
            //序列化
            case 1:
                $value = (array)unserialize($value);
                break;
            //json
            case 2:
                $value = (array)json_decode($value);
                break;
            //字符串,不经过任何处理,默认
            case 0:
            default:
                break;
        }
        if(!is_string($value)){
            //确保取得数组类型的数据
            $value = object2array($value);
        }
        return $value;
    }
    /**
     * @name 修改
     * @param array $data 添加的数据
     * @param int $value_type 值保存方式  0:string,1:serialize,2:json
     * @param string $version_key 配置版本的key
     */
    public function editConfig($data = [],$value_type = 0,$version_key = 'config_version'){
        $data = $this->validateData($data);
        if(isset($data['value'])){
            switch($value_type){
                //序列化
                case 1:
                    $data['value'] = serialize((array)$data['value']);
                    $data['value_type'] = 1;
                    break;
                //json
                case 2:
                    $data['value'] = json_encode((array)$data['value']);
                    $data['value_type'] = 2;
                    break;
                //字符串,不经过任何处理,默认
                case 0:
                default:
                    $data['value_type'] = 0;
                    break;
            }
        }
        $data['update_time'] = NOW_TIME;
        $res = 0;
        if($res = $this->save($data)){
            $version_key = $version_key ?:'config_version';
            if(array_key_exists($version_key,$this->zip_conf_list)){
                return $res;
            }
            //更新版本号
            $this->update_version($version_key);
            /** 自动打包 **/
            //if(array_key_exists($version_key,$this->zip_conf_list)){
            //    $this->zip_conf($this->zip_conf_list[$version_key]);
            //}
        }
        return $res;
    }
    /**
     * @name 更新版本号
     */
    public function update_version($version_key = ''){
        if(!$version_key) return false;
        $has = $this->hasKey($version_key,$version_key);
        $mt_varsion = date('Ymds').mt_rand(1000,9999);
        if(!$has){
            return $this->addConfig([
                'type'  => $version_key,
                'key'   => $version_key,
                'value' => $mt_varsion,
                'description' => '配置版本号',
            ]);
        }else{
            return $this->where(['type'=>$version_key,'key'=>$version_key])->save(['value'=>$mt_varsion]);
        }
    }
    /**
     * @name 打包配置
     */
    public function zip_conf($config_name = ''){
        $conf_data = $this->ApiServiceGetConf($config_name);
        $zip = new \ZipArchive();
        if($zip->open('public/confdata/'.$config_name.'.zip', \ZipArchive::OVERWRITE)=== TRUE){
            $this->addFileToZip($config_name.'.json', $zip,$conf_data); //调用方法，对要打包的根目录进行操作，并将ZipArchive的对象传递给方法
            $zip->close(); //关闭处理的zip文件
            return true;
        }else{
	    $filepath = 'public/confdata/'.$config_name.'.zip';
	    @unlink($filepath);
	    if($zip->open($filepath, \ZIPARCHIVE::CREATE) === TRUE){
		$this->addFileToZip($config_name.'.json', $zip,$conf_data); //调用方法，对要打包的根目录进行操作，并将ZipArchive的对象传递给方法
		$zip->close(); //关闭处理的zip文件
		return true;
	    }
	}
        return false;
    }
    /**
     * @name 添加数据到压缩包
     */
    public function addFileToZip($path,$zip,$data){
        if(is_dir($path)){
            $handler = opendir($path); //打开当前文件夹由$path指定。
            while(($filename=readdir($handler))!==false){
                if($filename != "." && $filename != ".."){
			//文件夹文件名字为'.'和‘..’，不要对他们进行操作
                    if(is_dir($path."/".$filename)){
			// 如果读取的某个对象是文件夹，则递归
                        $this->addFileToZip($path."/".$filename, $zip);
                    }else{
			 //将文件加入zip对象
                        $zip->addFile($path."/".$filename);
                    }
                }
            }
            @closedir($path);
        }else{
            $zip->addFromString($path,json_encode($data));
        }
    }
    /**
     * @name 删除
     */
    public function deleteConfig($config_id = 0){
        if($config_id){
            $info = $this->getConfigById($config_id);
            if($this->where(['config_id'=>$config_id])->delete()){
                //删除信息成功,删除附件
                $attach_id = isset($info['value']['image']) ? $info['value']['image'] : 0;
                if($attach_id){
                    return model('attach/Attach')->deleteAttachById($attach_id);
                }
                return true;
            }
        }
        return false;
    }
    /**
     * @name API service 获取配置服务
     */
    public function ApiServiceGetConf($type = '',$hasKey = false){
        $list = [];
        if($type){
            $map['type'] = $this->getRelConfigType($type);
            $resType = (is_array($map['type']) && isset($map['type'][2])) ? $map['type'][2] : '__array__';
            array_pop($map['type']);
            $map['status'] = 1;
            $res = $this->where($map)->select();
            if(!empty($res)){
                foreach($res as $v){
                    //获取配置值
                    $value = $this->getReValue($v['value'],$v['value_type']);
                    //检测配置值中是否有图片
                    if(isset($value['image'])){
                        $value['image'] = getImageUrl($value['image'],0);
                    }
                    //获取配置的键名
                    $relType = is_array($map['type']) ? array_search($v['type'],$map['type'][1]) : $map['type'];
                    //$value = ($resType === '__string__') ? (string)$value :  $value;
                    //是否需要返回数据中的key值
                    if($hasKey){
                        $list[$relType][$v['key']] = $value;
                    }else{
                        //自动检索并获取配置
                        if(is_string($value) && $resType === '__string__'){
                            $list[$relType] = $value;
                        }else{
                            $list[$relType][] = $value;
                        }
                    }
                    
                }
            }
        }
        if($list){
            if($map['type'] && is_array($map['type'][1])){
                foreach($map['type'][1] as $k => $v){
                    !isset($list[$k]) && $list[$k] = [];
                }
            }
            return is_array($map['type']) ? $list : current($list);
        }
        return [];
    }
    /**
     * @name 获取配置的类型名称查询条件 
     */
    protected function getRelConfigType($type){
        switch($type){
            case 'filter':
                $relType = ['in',['live'=>'stream_live','video'=>'stream_video'],'__array__'];
                break;
            case 'filter_word_config':
                $relType = ['in',['filter_word_version'=>'filter_version','filter_word_replace'=>'filter_word_config'],'__string__'];
                break;
            default:
                $relType = $type;
                break;
        }
        return $relType;
    }
}
